package com.whpost.service.tools;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Hex;
import org.springframework.stereotype.Service;

import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Security;

public class Aes {
    /**
     *
     * @author ngh
     * AES128 算法
     *
     * CBC 模式
     *
     * PKCS7Padding 填充模式
     *
     * CBC模式需要添加偏移量参数iv，必须16位
     * 密钥 sessionKey，必须16位
     *
     * 介于java 不支持PKCS7Padding，只支持PKCS5Padding 但是PKCS7Padding 和 PKCS5Padding 没有什么区别
     * 要实现在java端用PKCS7Padding填充，需要用到bouncycastle组件来实现
     */
    // 算法名称
    private static String KEY_ALGORITHM = "AES";
    // 加解密算法/模式/填充方式
    private static String algorithmStr = "AES/CBC/PKCS7Padding";
    // 偏移量 16位
    private static String myIv = "0102030405060708";

    //默认值
    private static final String MY_KEY = "W36BQGe8gbNCagac";

    /**
     *
     * @param content
     * @param myKey
     * @return
     * @throws NoSuchPaddingException
     * @throws NoSuchAlgorithmException
     * @throws NoSuchProviderException
     */
    public static String encrypt(String content,String myKey) throws NoSuchPaddingException, NoSuchAlgorithmException, NoSuchProviderException {
        if ("0".equals(myKey)) myKey = MY_KEY;
        byte[] encryptedText = null;
        byte[] contentByte = content.getBytes();
        // 初始化
        Security.addProvider(new BouncyCastleProvider());
        // 转化成JAVA的密钥格式
        Key key = new SecretKeySpec(myKey.getBytes(), KEY_ALGORITHM);
        Cipher cipher = Cipher.getInstance(algorithmStr, "BC");;
        try {
            cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(myIv.getBytes()));
            encryptedText = cipher.doFinal(contentByte);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return new String(Hex.encode(encryptedText));
    }

    /**
     *
     * @param encryptedData
     * @return
     */
    public static String decrypt(String encryptedData,String myKey) {
        if ("0".equals(myKey)) myKey = MY_KEY;
        byte[] encryptedText = null;
        byte[] encryptedDataByte = Hex.decode(encryptedData);

        try {
            // 初始化
            Security.addProvider(new BouncyCastleProvider());
            // 转化成JAVA的密钥格式
            Key key = new SecretKeySpec(myKey.getBytes(), KEY_ALGORITHM);
            Cipher cipher = Cipher.getInstance(algorithmStr, "BC");;

            cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(myIv.getBytes()));
            encryptedText = cipher.doFinal(encryptedDataByte);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return new String(encryptedText);
    }

    public static void main(String[] args) throws NoSuchPaddingException, NoSuchAlgorithmException, NoSuchProviderException {

        String str =  "123";
        String jiamh = Aes.encrypt(str,"J1bfgSUWKOrpBggm");
        String jiemh = Aes.decrypt(jiamh,"J1bfgSUWKOrpBggm");
        System.out.println("原文："+str);
        System.out.println("加密后："+jiamh);
        System.out.println("解密后："+jiemh);
    }
}